Lietuvių

Atskleiskite GraphQL Federacijos galią su Schemos Sujungimu. Išmokite kurti vieningą GraphQL API iš kelių servisų, gerindami mastelį ir priežiūrą.

GraphQL Federacija: Schemos Sujungimas (Schema Stitching) - Išsamus Vadovas

Nuolat besikeičiančioje modernių programų kūrimo aplinkoje būtinybė turėti mastelį didinančias ir lengvai prižiūrimas architektūras tapo svarbiausia. Mikroservisai, pasižymintys moduliškumu ir nepriklausomu diegiamumu, tapo populiariu sprendimu. Tačiau daugybės mikroservisų valdymas gali sukelti sudėtingumų, ypač kai reikia pateikti vieningą API kliento aplikacijoms. Būtent čia į pagalbą ateina GraphQL Federacija, o konkrečiai – Schemos Sujungimas.

Kas yra GraphQL Federacija?

GraphQL Federacija yra galinga architektūra, leidžianti sukurti vieną, vieningą GraphQL API iš kelių pagrindinių GraphQL servisų (dažnai atstovaujančių mikroservisus). Ji leidžia programuotojams teikti užklausas duomenims iš skirtingų servisų taip, lyg tai būtų vienas grafas, supaprastinant kliento patirtį ir sumažinant sudėtingos orkestravimo logikos poreikį kliento pusėje.

Yra du pagrindiniai požiūriai į GraphQL Federaciją:

Šiame straipsnyje dėmesys skiriamas Schemos Sujungimui, nagrinėjant jo koncepcijas, privalumus, apribojimus ir praktinį įgyvendinimą.

Schemos Sujungimo Supratimas

Schemos sujungimas yra procesas, kurio metu kelios GraphQL schemos sujungiamos į vieną, vientisą schemą. Ši vieninga schema veikia kaip fasadas, slepiantis pagrindinių servisų sudėtingumą nuo kliento. Kai klientas pateikia užklausą sujungtai schemai, sąsaja protingai nukreipia užklausą į atitinkamą pagrindinį servisą (-us), gauna duomenis ir sujungia rezultatus prieš grąžindama juos klientui.

Pagalvokite apie tai taip: turite kelis restoranus (servisus), kurių kiekvienas specializuojasi skirtingose virtuvėse. Schemos sujungimas yra tarsi universalus meniu, kuris apjungia visus patiekalus iš kiekvieno restorano. Kai klientas užsisako iš universalaus meniu, užsakymas protingai nukreipiamas į atitinkamas restoranų virtuves, maistas paruošiamas ir sujungiamas į vieną pristatymą klientui.

Pagrindinės Schemos Sujungimo Koncepcijos

Schemos Sujungimo Privalumai

Schemos sujungimas siūlo keletą įtikinamų privalumų organizacijoms, taikančioms mikroservisų architektūrą:

Schemos Sujungimo Apribojimai

Nors Schemos Sujungimas siūlo daugybę privalumų, svarbu žinoti jo apribojimus:

Praktinis Schemos Sujungimo Įgyvendinimas

Panagrinėkime supaprastintą pavyzdį, kaip įgyvendinti Schemos Sujungimą naudojant Node.js ir graphql-tools biblioteką (populiarus pasirinkimas schemų sujungimui). Šis pavyzdys apima du mikroservisus: Vartotojų Servisą ir Produktų Servisą.

1. Apibrėžkite Nuotolines Schemas

Pirmiausia, apibrėžkite GraphQL schemas kiekvienam nuotoliniam servisui.

Vartotojų Servisas (user-service.js):


const { buildSchema } = require('graphql');

const userSchema = buildSchema(`
  type User {
    id: ID!
    name: String
    email: String
  }

  type Query {
    user(id: ID!): User
  }
`);

const users = [
  { id: '1', name: 'Alice Smith', email: 'alice@example.com' },
  { id: '2', name: 'Bob Johnson', email: 'bob@example.com' },
];

const userRoot = {
  user: (args) => users.find(user => user.id === args.id),
};

module.exports = {
  schema: userSchema,
  rootValue: userRoot,
};

Produktų Servisas (product-service.js):


const { buildSchema } = require('graphql');

const productSchema = buildSchema(`
  type Product {
    id: ID!
    name: String
    price: Float
    userId: ID!  # Svetimasis raktas į Vartotojų Servisą
  }

  type Query {
    product(id: ID!): Product
  }
`);

const products = [
  { id: '101', name: 'Laptop', price: 1200, userId: '1' },
  { id: '102', name: 'Smartphone', price: 800, userId: '2' },
];

const productRoot = {
  product: (args) => products.find(product => product.id === args.id),
};

module.exports = {
  schema: productSchema,
  rootValue: productRoot,
};

2. Sukurkite Sąsajos Servisą (Gateway)

Dabar sukurkite sąsajos servisą, kuris sujungs abi schemas.

Sąsajos Servisas (gateway.js):


const { stitchSchemas } = require('@graphql-tools/stitch');
const { makeRemoteExecutableSchema } = require('@graphql-tools/wrap');
const { graphqlHTTP } = require('express-graphql');
const express = require('express');
const { introspectSchema } = require('@graphql-tools/wrap');
const { printSchema } = require('graphql');
const fetch = require('node-fetch');

async function createRemoteSchema(uri) {
  const fetcher = async (params) => {
    const response = await fetch(uri, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify(params),
    });
    return response.json();
  };

  const schema = await introspectSchema(fetcher);
  return makeRemoteExecutableSchema({
    schema,
    fetcher,
  });
}

async function main() {
  const userSchema = await createRemoteSchema('http://localhost:4001/graphql');
  const productSchema = await createRemoteSchema('http://localhost:4002/graphql');

  const stitchedSchema = stitchSchemas({
    subschemas: [
      { schema: userSchema },
      { schema: productSchema },
    ],
    typeDefs: `
      extend type Product {
        user: User
      }
    `,
    resolvers: {
      Product: {
        user: {
          selectionSet: `{ userId }`,
          resolve(product, args, context, info) {
            return info.mergeInfo.delegateToSchema({
              schema: userSchema,
              operation: 'query',
              fieldName: 'user',
              args: {
                id: product.userId,
              },
              context,
              info,
            });
          },
        },
      },
    },
  });

  const app = express();
  app.use('/graphql', graphqlHTTP({
    schema: stitchedSchema,
    graphiql: true,
  }));

  app.listen(4000, () => console.log('Gateway server running on http://localhost:4000/graphql'));
}

main().catch(console.error);

3. Paleiskite Servisus

Jums reikės paleisti Vartotojų servisą ir Produktų servisą skirtinguose prievaduose. Pavyzdžiui:

Vartotojų Servisas (prievadas 4001):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./user-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4001, () => console.log('User service running on http://localhost:4001/graphql'));

Produktų Servisas (prievadas 4002):


const express = require('express');
const { graphqlHTTP } = require('express-graphql');
const { schema, rootValue } = require('./product-service');

const app = express();
app.use('/graphql', graphqlHTTP({
  schema: schema,
  rootValue: rootValue,
  graphiql: true,
}));

app.listen(4002, () => console.log('Product service running on http://localhost:4002/graphql'));

4. Pateikite Užklausą Sujungtai Schemai

Dabar galite pateikti užklausą sujungtai schemai per sąsają (veikiančią prievade 4000). Galite paleisti tokią užklausą:


query {
  product(id: "101") {
    id
    name
    price
    user {
      id
      name
      email
    }
  }
}

Ši užklausa gauna produktą su ID "101" ir taip pat paima susijusį vartotoją iš Vartotojų Serviso, demonstruodama, kaip Schemos Sujungimas leidžia teikti užklausas duomenims iš kelių servisų vienoje užklausoje.

Pažangios Schemos Sujungimo Technikos

Be pagrindinio pavyzdžio, štai keletas pažangių technikų, kurias galima naudoti norint patobulinti Schemos Sujungimo įgyvendinimą:

Pasirinkimas Tarp Schemos Sujungimo ir Apollo Federacijos

Nors Schemos Sujungimas yra perspektyvus pasirinkimas GraphQL Federacijai, Apollo Federacija tapo populiaresniu pasirinkimu dėl savo pažangių funkcijų ir pagerintos programuotojo patirties. Štai abiejų požiūrių palyginimas:

Savybė Schemos Sujungimas Apollo Federacija
Schemos Apibrėžimas Naudoja esamą GraphQL schemos kalbą Naudoja deklaratyvią schemos kalbą su direktyvomis
Užklausų Planavimas Reikalingas rankinis užklausų delegavimas Automatinis užklausų planavimas Apollo sąsajoje
Tipų Plėtiniai Ribotas palaikymas Integruotas tipų plėtinių palaikymas
Raktų Direktyvos Nepalaikoma Naudoja @key direktyvą esybėms identifikuoti
Paskirstytasis Sekimas Reikalingas rankinis įgyvendinimas Integruotas paskirstytojo sekimo palaikymas
Įrankiai ir Ekosistema Mažiau brandūs įrankiai Brandesni įrankiai ir didelė bendruomenė
Sudėtingumas Gali būti sudėtinga valdyti didelėse sistemose Sukurta didelėms ir sudėtingoms sistemoms

Kada Rinktis Schemos Sujungimą:

Kada Rinktis Apollo Federaciją:

Realūs Pavyzdžiai ir Panaudojimo Atvejai

Štai keletas realaus pasaulio pavyzdžių, kaip gali būti naudojama GraphQL Federacija, įskaitant Schemos Sujungimą:

Geriausios Schemos Sujungimo Praktikos

Norėdami užtikrinti sėkmingą Schemos Sujungimo įgyvendinimą, laikykitės šių geriausių praktikų:

Išvada

GraphQL Federacija su Schemos Sujungimu siūlo galingą požiūrį į vieningų API kūrimą iš kelių servisų mikroservisų architektūroje. Suprasdami jos pagrindines koncepcijas, privalumus, apribojimus ir įgyvendinimo technikas, galite panaudoti Schemos Sujungimą, kad supaprastintumėte duomenų prieigą, pagerintumėte mastelį ir padidintumėte priežiūros patogumą. Nors Apollo Federacija tapo pažangesniu sprendimu, Schemos Sujungimas išlieka perspektyvus pasirinkimas paprastesniems scenarijams arba integruojant esamus GraphQL servisus. Atidžiai apsvarstykite savo specifinius poreikius ir reikalavimus, kad pasirinktumėte geriausią požiūrį savo organizacijai.